#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

#include "net.h"
#include "server.h"

//全局变量
MSG msg;
int cameraFlag = 0;
pthread_t threadID1 = 0;
pthread_t threadID2 = 0;

void toDevice(char *buf, int userId, int deviceId)
{
	printf("status is -------->%s\r\n", buf);

	if (NULL == buf)
	{
		printf("status error! \r\n");
		return;
	}

	if (0 >= userId)
	{
		printf("userId error!\r\n");
		return;
	}

	if (0 >= deviceId)
	{
		printf("deviceId error!\r\n");
		return;
	}
	
	//记录用户描述符
	msg.userId = userId;
	printf("op ==%d, userOrDevice == %d, userid == %d, data ==%s\r\n", msg.op, msg.userOrDevice, msg.userId, msg.data);
	send(deviceId, &msg, sizeof(msg), 0);
	printf("send to %d ok!\r\n", deviceId);
}

void cameraInit()
{
	cameraFlag = 1;
	system("./camera");
	printf("camera ok!\r\n");
	cameraFlag = 0;
	pthread_exit(NULL);
	return;
}

void clientServer()
{
	int socketID = 0;
	int newID = 0;
	int user = 0;
	int addrLength = 0;
	int ret = 0;
	int retu = 0;
	int num = 0;
	int status = 0;

	struct sockaddr_in addr;
	//设备保存数组
	char devices[32] = {0};
	//用户保存数组
	int users[10] = {0};
	//用户保存数组下标
	int userNo = 0;

	int maxFd = 0;
	int index = 0;
	fd_set readFds;
	fd_set tmpFds;

	//初始化套接字
	socketID = initSocket();

	if (socketID < 0)
	{
		return;
	}

	//多路复用
	maxFd = socketID;
	FD_ZERO(&readFds);
	FD_ZERO(&tmpFds);
	FD_SET(socketID, &readFds);
	tmpFds = readFds;

	while (1)
	{
		readFds = tmpFds;
		ret = select(maxFd + 1, &readFds, NULL, NULL, NULL);

		if (ret < 0)
		{
			perror("select error");
			break;
		}

		for (index = 0; index <= maxFd; index++)
		{
			//判断哪个描述可操作
			if (FD_ISSET(index, &readFds))
			{
				if (index == socketID)
				{
					//接受连接
					addrLength = sizeof(addr);
					memset(&addr, 0, addrLength);

					newID = accept(socketID, (struct sockaddr *)(&addr), &addrLength);
					if (newID < 0)
					{
						perror("accept error");
						return -1;
					}

					printf("客户端连接成功, ip=%s,port=%d\r\n", (char *)inet_ntoa(addr.sin_addr.s_addr), ntohs(addr.sin_port));

					FD_SET(newID, &tmpFds);
					if (newID > maxFd)
						maxFd = newID;
				}
				else
				{
					memset(&msg, 0, sizeof(MSG));

					ret = recv(index, &msg, sizeof(MSG), 0);

					if (ret <= 0)
					{
						close(index);
						
						int i;
						for(i = 0; i < 10; i++)
						{
							if( index == users[i])
							{
								users[i] = 0;
							}
						}

						FD_CLR(index, &tmpFds);
						continue;
					}

					else
					{
						//客户连接----------------------》
						if (msg.userOrDevice == USER)						
						{
							printf("用户请求：op---%d  usrOrDevice---%d userId---%d data---%s\r\n", msg.op, msg.userOrDevice, msg.userId, msg.data);

							if(10 <= userNo)
							{
								printf("用户已满\r\n");
								strcpy(msg.data, "用户已满，请稍后重试");
								send(index, &msg, sizeof(msg), 0);
								continue;
							}	

							users[userNo] = index;
							//记录用户描述符
							if (users[userNo] != index)
							{
								userNo++;
								users[userNo] = index;
							}

							switch (msg.op)
							{
							case LOGIN:
								printf("客户端请求登录，密码为：%s\r\n", msg.data);
								ret = login(msg.data);
								if (ret == ERROR)
								{
									msg.op = ERROR;
								}
								else
								{
									msg.op = OK;
								}
								send(index, &msg, sizeof(msg), 0);
								printf("发送给客户端成功！\r\n");
								toDevice(msg.data, index, devices[TEMP]);
								continue;
								break;
								
							case CAMERA:
								printf("收到摄像请求:%s\r\n", msg.data);
								//启动摄像头服务器
								if(0 == cameraFlag)
								{
									strcpy(msg.data, "摄像头空闲");
									printf("发送给用户：op---%d  usrOrDevice---%d userId---%d data---%s\r\n", msg.op, msg.userOrDevice, msg.userId, msg.data);
									send(index, &msg, sizeof(msg), 0);
									pthread_create(&threadID1,NULL,cameraInit,NULL);
								}
								else
								{
									strcpy(msg.data, "摄像头忙");
									printf("发送给用户：op---%d  usrOrDevice---%d userId---%d data---%s\r\n", msg.op, msg.userOrDevice, msg.userId, msg.data);
									send(index, &msg, sizeof(msg), 0);
								}
								
								break;
							case LIGHT:
								printf("收到客户灯光请求:%s\r\n", msg.data);
								toDevice(msg.data, index, devices[LIGHT]);
								break;
							case AIRCON:
								printf("收到客户空调请求:%s\r\n", msg.data);
								toDevice(msg.data, index, devices[AIRCON]);
								break;
							case TEMP:
								printf("收到客户端温度请求:%s\r\n", msg.data);
								toDevice(msg.data, index, devices[TEMP]);
								break;
							case INF_RAY:
								printf("收到客户端人体感应请求:%s\r\n", msg.data);
								toDevice(msg.data, index, devices[INF_RAY]);
								break;
							case LIGHT_RAY:
								printf("收到客户端光敏请求:%s\r\n", msg.data);
								toDevice(msg.data, index, devices[LIGHT_RAY]);
								break;
							case MOD:
								printf("收到客户端切换模式请求:%s\r\n",msg.data);
								toDevice(msg.data, index, devices[LIGHT]);
								toDevice(msg.data, index, devices[AIRCON]);
								if((0 == strcmp(msg.data,"睡眠模式")) || (0 == strcmp(msg.data,"无人模式")))
								{
									if(0 == cameraFlag)
									{
										strcpy(msg.data, "摄像头空闲");
										printf("发送给用户：op---%d  usrOrDevice---%d userId---%d data---%s\r\n", msg.op, msg.userOrDevice, msg.userId, msg.data);
										send(index, &msg, sizeof(msg), 0);
										printf("创建摄像头线程\r\n");
										pthread_create(&threadID1,NULL,cameraInit,index);
									}
									else
									{
										strcpy(msg.data, "摄像头忙");
										printf("发送给用户：op---%d  usrOrDevice---%d userId---%d data---%s\r\n", msg.op, msg.userOrDevice, msg.userId, msg.data);
										send(index, &msg, sizeof(msg), 0);
									}			
								}
								break;
							default:
								printf("请输入正确的选项：\n");
								break;
							}
							memset(&msg, 0, sizeof(MSG));
						}

						//设备连接----------------------------------》
						else if (msg.userOrDevice == DEVICE)
						{
							printf("模块返回：op---%d  usrOrDevice---%d userId---%d data---%s\r\n", msg.op, msg.userOrDevice, msg.userId, msg.data);
							//WIFI模块第一次连接，记录WIFI模块下连接的设备
							if (msg.userId == FIREST)
							{
								printf("模块第一次连接...\r\n");

								int i;
								for (i = 0; i < sizeof(msg.data); i++)
								{
									if ('1' == msg.data[i])
									{
										printf("devices[%d] == %d\r\n", i, index);
										devices[i] = index;
									}
								}
							}

							switch (msg.op)
							{
							case LIGHT:
								printf("收到设备---灯光返回\r\n");
								break;
							case AIRCON:
								printf("收到设备---空调返回:%s\r\n", msg.data);
								break;
							case SMOG:

								printf("收到设备---烟雾传感器信息：%s\r\n", msg.data);

								if (0 == strcmp(msg.data, "SMOGwarning"))
								{
									int i = 0;
									for (i = 0; i < 9; i++)
									{
										if (users[i] != 0)
										{
											printf("警告发送给用户：op---%d  usrOrDevice---%d userId---%d data---%s\r\n", msg.op, msg.userOrDevice, msg.userId, msg.data);
											send(users[i], &msg, sizeof(msg), 0);
										}
									}
									continue;
								}
								
								break;
							case TEMP:
								printf("收到设备---温度传感器信息：%s\r\n", msg.data);
								break;
							case HUM:
								printf("收到设备---湿度传感器信息：%s\r\n", msg.data);
								break;
							case INF_RAY:
								printf("收到设备---人体传感器信息：%s\r\n", msg.data);

								//群发给客户端
								if (0 == strcmp(msg.data, "INF_RAYwarning"))
								{
									int i = 0;
									for (i = 0; i < 9; i++)
									{
										if (users[i] != 0)
										{
											printf("警告发送给用户：op---%d  usrOrDevice---%d userId---%d data---%s\r\n", msg.op, msg.userOrDevice, msg.userId, msg.data);
											send(users[i], &msg, sizeof(msg), 0);
										}
									}
									continue;
								}

								break;

							case LIGHT_RAY:
								printf("收到设备---光敏传感器信息：%s\r\n", msg.data);
								break;
							default:
								printf("in default\r\n");
								msg.op = -123;
								msg.userOrDevice = -1111;
								msg.userId = -222;
								strcpy(msg.data, "服务器收到\r\n");
								send(index, &msg, sizeof(msg), 0);
								continue;
								break;
							}
							printf("发送给用户：op---%d  usrOrDevice---%d userId---%d data---%s\r\n", msg.op, msg.userOrDevice, msg.userId, msg.data);
							send(msg.userId, &msg, sizeof(msg), 0);
						}
						memset(&msg, 0, sizeof(MSG));
					} //else if ret > 0
				}	 //else if index != socketID
			}		  // if !FD_ISSET
		}			  //for index
	}				  //while 1
	close(socketID);
	closeDatabase();
	pthread_exit(NULL);
	return;
}

int main()
{
	API();
	//初始化数据库
	initDatabase();
	pthread_create(&threadID2, NULL, clientServer, NULL);

	pthread_join(threadID2,  NULL);
	printf("clientServer thread stop\r\n");
	return 0;
}
